\section{Network address calculation example}

As we know, a TCP/IP address (IPv4) consists of four numbers in the $0 \ldots 255$ range, i.e., four bytes.

Four bytes can be fit in a 32-bit variable easily, so an IPv4 host address, network mask or network address
can all be 32-bit integers.

From the user's point of view, the network mask is defined as four numbers and is formatted like 255.255.255.0 or so,
but network engineers (sysadmins) use a more compact notation (\ac{CIDR}), like \q{/8}, \q{/16}, etc.

This notation just defines the number of bits the mask has, starting at the \ac{MSB}.

\small
\begin{center}
\begin{tabular}{ | l | l | l | l | l | l | }
\hline
\HeaderColor Mask & 
\HeaderColor Hosts & 
\HeaderColor Usable &
\HeaderColor Netmask &
\HeaderColor Hex mask &
\HeaderColor \\
\hline
/30  & 4        & 2        & 255.255.255.252  & 0xfffffffc  & \\
\hline
/29  & 8        & 6        & 255.255.255.248  & 0xfffffff8  & \\
\hline
/28  & 16       & 14       & 255.255.255.240  & 0xfffffff0  & \\
\hline
/27  & 32       & 30       & 255.255.255.224  & 0xffffffe0  & \\
\hline
/26  & 64       & 62       & 255.255.255.192  & 0xffffffc0  & \\
\hline
/24  & 256      & 254      & 255.255.255.0    & 0xffffff00  & class C network \\
\hline
/23  & 512      & 510      & 255.255.254.0    & 0xfffffe00  & \\
\hline
/22  & 1024     & 1022     & 255.255.252.0    & 0xfffffc00  & \\
\hline
/21  & 2048     & 2046     & 255.255.248.0    & 0xfffff800  & \\
\hline
/20  & 4096     & 4094     & 255.255.240.0    & 0xfffff000  & \\
\hline
/19  & 8192     & 8190     & 255.255.224.0    & 0xffffe000  & \\
\hline
/18  & 16384    & 16382    & 255.255.192.0    & 0xffffc000  & \\
\hline
/17  & 32768    & 32766    & 255.255.128.0    & 0xffff8000  & \\
\hline
/16  & 65536    & 65534    & 255.255.0.0      & 0xffff0000  & class B network \\
\hline
/8   & 16777216 & 16777214 & 255.0.0.0        & 0xff000000  & class A network \\
\hline
\end{tabular}
\end{center}
\normalsize

Here is a small example, which calculates the network address by applying the network mask to the host address.

\lstinputlisting[style=customc]{\CURPATH/netmask.c}

\subsection{calc\_network\_address()}

\TT{calc\_network\_address()} function is simplest one: 
it just ANDs the host address with the network mask, resulting in the network address.

\lstinputlisting[caption=\Optimizing MSVC 2012 /Ob0,numbers=left,style=customasmx86]{\CURPATH/calc_network_address_MSVC_2012_Ox.asm}

At line 22 we see the most important \AND---here the network address is calculated.

\subsection{form\_IP()}

The \TT{form\_IP()} function just puts all 4 bytes into a 32-bit value.

Here is how it is usually done:

\begin{itemize}
\item Allocate a variable for the return value.  Set it to 0.

\item Take the fourth (lowest) byte, apply OR operation to this byte and return the value.
The return value contain the 4th byte now.

\item Take the third byte, shift it left by 8 bits.
You'll get a value like \TT{0x0000bb00} where \TT{bb} is your third byte.
Apply the OR operation to the resulting value and it.
The return value has contained \TT{0x000000aa} so far, so ORing the values will produce a value 
like \TT{0x0000bbaa}.

\item Take the second byte, shift it left by 16 bits.
You'll get a value like \TT{0x00cc0000}, where \TT{cc} is your second byte.
Apply the OR operation to the resulting value and return it.
The return value has contained \TT{0x0000bbaa} so far, so ORing the values will produce
a value like \TT{0x00ccbbaa}.

\item Take the first byte, shift it left by 24 bits.
You'll get a value like \TT{0xdd000000}, where \TT{dd} is your first byte.
Apply the OR operation to the resulting value and return it.
The return value contain \TT{0x00ccbbaa} so far, so ORing the values will produce
a value like \TT{0xddccbbaa}.

\end{itemize}

And this is how it's done by non-optimizing MSVC 2012:

\lstinputlisting[caption=\NonOptimizing MSVC 2012,style=customasmx86]{\CURPATH/form_IP_MSVC_2012_EN.asm}

Well, the order is different, but, of course, the order of the operations doesn't matter.

\Optimizing MSVC 2012 does essentially the same, but in a different way:

\lstinputlisting[caption=\Optimizing MSVC 2012 /Ob0,style=customasmx86]{\CURPATH/form_IP_MSVC_2012_Ox_EN.asm}

We could say that each byte is written to the lowest 8 bits of the return value, 
and then the return value is shifted left by one byte at each step.

Repeat 4 times for each input byte.

\par
That's it! Unfortunately, there are probably no other ways to do it.

There are no popular \ac{CPU}s or \ac{ISA}s which has instruction for composing a value from
bits or bytes.

It's all usually done by bit shifting and ORing.

\subsection{print\_as\_IP()}

\TT{print\_as\_IP()} does the inverse: splitting a 32-bit value into 4 bytes.

Slicing works somewhat simpler: just shift input value by 24, 16, 8 or 0 bits, take the 
bits from zeroth to seventh (lowest byte), and that's it:

\lstinputlisting[caption=\NonOptimizing MSVC 2012,style=customasmx86]{\CURPATH/print_as_IP_MSVC_2012_EN.asm}

\Optimizing MSVC 2012 does almost the same, but without unnecessary reloading of the input value:

\lstinputlisting[caption=\Optimizing MSVC 2012 /Ob0,style=customasmx86]{\CURPATH/print_as_IP_MSVC_2012_Ox.asm}

\subsection{form\_netmask() and set\_bit()}

\TT{form\_netmask()} makes a network mask value from \ac{CIDR} notation.
Of course, it would be much effective to use here some kind of a precalculated table, but we consider it in this
way intentionally, to demonstrate bit shifts.

We will also write a separate function \TT{set\_bit()}. 
It's a not very good idea to create a function
for such primitive operation, but it would be easy to understand how it all works.

\lstinputlisting[caption=\Optimizing MSVC 2012 /Ob0,style=customasmx86]{\CURPATH/form_netmask_MSVC_2012_Ox.asm}

\TT{set\_bit()} is primitive: it just shift left 1 to number of bits we need and then 
ORs it with the \q{input} value.
\TT{form\_netmask()} has a loop: it will set as many bits (starting from the \ac{MSB}) as 
passed in the \TT{netmask\_bits} argument

\subsection{Summary}

That's it!
We run it and getting:

\begin{lstlisting}
netmask=255.255.255.0
network address=10.1.2.0
netmask=255.0.0.0
network address=10.0.0.0
netmask=255.255.255.128
network address=10.1.2.0
netmask=255.255.255.192
network address=10.1.2.64
\end{lstlisting}
